﻿using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.DirectoryServices;
using System.Configuration;
using System.Text;

namespace CustomSignature.Layouts.CustomSignature
{
    public partial class MultipleSignatureTask : LayoutsPageBase
    {
        #region Global variables
        int documentID = 0;
        DataTable dtDocDetails = new DataTable();
        string userFullName = string.Empty;
        int userCount = 100;
        #endregion

        #region Get values from web.config
        string siteURL = ConfigurationSettings.AppSettings["SiteURL"];
        string listDocumentLibrary = ConfigurationSettings.AppSettings["MultipleSignDocumentLibrary"];
        string listWorkFlowHistory = ConfigurationSettings.AppSettings["MultipleSignWorkflowHistory"];
        string documentLibraryURL = ConfigurationSettings.AppSettings["MultipleSignDocumentLibraryURL"];
        string documentNotAvailable = ConfigurationSettings.AppSettings["DocumentNotAvailable"];
        #endregion

        public static string Srt
        { get; set; }
        protected void Page_Load(object sender, EventArgs e)
        {
            bool isValidUser = false;
            if (!IsPostBack)
            {
                ddlPurposeofSigning.SelectedIndex = 0;
            }
            if (Request.QueryString["DocumentID"] != null)
            {
                documentID = Convert.ToInt32(Request.QueryString["DocumentID"]);
                dtDocDetails = GetDocumentDetails();
                if (dtDocDetails != null)
                {
                    txtRejectedComments.Visible = false;
                    LoadDocumentInformationDetails();
                    txtLoginName.Text = Context.User.Identity.Name.ToString();
                    string signers = dtDocDetails.Rows[0]["Title"].ToString();
                    string[] multiUser = signers.Split(";".ToCharArray());
                    string loggedInUser = string.Empty;
                    txtDisplayName.Text = GetFullName();
                    for (int i = 0; i < multiUser.Length; i++)
                    {
                        if (multiUser[i].ToString().Trim() == Context.User.Identity.Name.ToString().Trim())
                        {
                            loggedInUser = multiUser[i];
                            userCount = i;
                            isValidUser = true;
                            break;
                        }
                        else
                        {
                            isValidUser = false;
                        }
                    }
                    if (!isValidUser)
                    {
                        lblMessage.Text = ConfigurationSettings.AppSettings["InvalidSigner"];
                    }
                }
                else
                {
                    lblMessage.Text = documentNotAvailable;
                }
            }
            else
            {
                lblMessage.Text = documentNotAvailable;
            }
            

        }
        /// <summary>
        /// Get Document details 
        /// </summary>
        /// <returns>DataTable</returns>
        protected DataTable GetDocumentDetails()
        {
            DataTable dtDocument = new DataTable();
            using (SPSite spSite = new SPSite(siteURL))
            {
                using (SPWeb spWeb = spSite.OpenWeb())
                {
                    SPQuery spQuery = new SPQuery();
                    string docQuery = string.Format("");
                    docQuery = string.Format("<Where><Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">{0}</Value></Eq></Where></Query>", documentID);
                    spQuery.Query = docQuery;
                    SPList spList = spWeb.Lists[listDocumentLibrary];
                    dtDocument = spList.GetItems(spQuery).GetDataTable();
                }
            }
            return dtDocument;
        }

        /// <summary>
        /// Load document information details for a document ID
        /// </summary>
        protected void LoadDocumentInformationDetails()
        {
            lnkDocumentID.Text = dtDocDetails.Rows[0]["ID"].ToString();
            txtDocumentName.Text = dtDocDetails.Rows[0]["FileLeafRef"].ToString();
            txtDocumentVersion.Text = dtDocDetails.Rows[0]["_UIVersionString"].ToString();
        }

        /// <summary>
        /// Method to validate the user credentials to sign a document
        /// </summary>
        /// <param name="domain"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns>Boolean returns true if success</returns>
        protected Boolean ValidateActiveDirectoryLogin(string domain, string username, string password)
        {
            Boolean success = false;

            System.DirectoryServices.DirectoryEntry Entry = new System.DirectoryServices.DirectoryEntry("LDAP://" + domain, username, password);
            DirectorySearcher searcher = new DirectorySearcher(Entry);
            searcher.SearchScope = System.DirectoryServices.SearchScope.Subtree;
            try
            {
                searcher.Filter = "(SAMAccountName=" + username + ")";
                searcher.PropertiesToLoad.Add("cn");
                System.DirectoryServices.SearchResult results = searcher.FindOne();
                // userFullName = results.GetDirectoryEntry().Properties["CN"].Value.ToString();
                success = (results != null);
            }
            catch (Exception ex)
            {
                success = false;
                lblMessage.Text = "Error: " + ex.Message;
            }
            return success;
        }


        /// <summary>
        /// Method to get full user name 
        /// </summary>
        /// <returns></returns>
        protected string GetFullName()
        {
            string userName = string.Empty;
            using (SPSite spSite = new SPSite(siteURL))
            {
                using (SPWeb spWeb = spSite.OpenWeb())
                {
                    userName = spWeb.CurrentUser.Name.ToString();
                }
            }
            return userName;
        }

        protected void btnSign_Click(object sender, EventArgs e)
        {
            bool isValidUser = false;
            bool isUpdated = false;
            string[] domainUser = Context.User.Identity.Name.Split('\\');
            isValidUser = ValidateActiveDirectoryLogin(domainUser[0], domainUser[1], txtPassword.Text);
            if (isValidUser)
            {
                isUpdated = UpdateDocumentStatus(ConfigurationSettings.AppSettings["Signed"]);
                if (isUpdated)
                {
                    lblMessage.Text = ConfigurationSettings.AppSettings["SuccessfullySigned"];
                    UpdateApprovalStatus();
                    CreateWorkflowHistory(true);
                }
                else
                {
                    CreateWorkflowHistory(false);
                }
                string url = documentLibraryURL;
                Response.Redirect(url);
            }
            else
            {
                lblMessage.Text = ConfigurationSettings.AppSettings["InvalidCredentials"];
                lblMessage.ForeColor = System.Drawing.Color.Red;
            }
        }

        /// <summary>
        /// To open the document on link of hyper link
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void lnkDocumentID_CLick(object sender, EventArgs e)
        {
            string url = documentLibraryURL + "/" + txtDocumentName.Text;
            StringBuilder script = new StringBuilder();
            script.Append("<script type=\"text/javascript\">"); script.Append("window.open('");
            script.Append(url);
            script.Append("');</script>");
        }

        protected void btnCancel_Click(object sender, EventArgs e)
        {
            string url = documentLibraryURL;
            Response.Redirect(url);
        }

        protected void ddlPurposeofSigning_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ddlPurposeofSigning.SelectedItem.Text == ConfigurationSettings.AppSettings["Rejected"])
            {
                txtRejectedComments.Visible = true;
            }
            else
            {
                txtRejectedComments.Visible = false;
            }
        }

        /// <summary>
        /// Method to update the document status
        /// </summary>
        /// <param name="status"></param>
        /// <returns>bool return true if updated</returns>
        protected bool UpdateDocumentStatus(string status)
        {
            bool updated = false;
            try
            {
                using (SPSite spSite = new SPSite(siteURL))
                {
                    using (SPWeb spWeb = spSite.OpenWeb())
                    {
                        SPQuery spQuery = new SPQuery();
                        string listQuery = string.Format("<Where><Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">{0}</Value></Eq></Where></Query>", documentID);
                        SPList spList = spWeb.Lists[listDocumentLibrary];
                        spQuery.Query = listQuery;
                        SPListItemCollection spListItems = spList.GetItems(spQuery);
                        foreach (SPListItem item in spListItems)
                        {
                            if (Convert.ToInt32(item["ID"]) == Convert.ToInt32(documentID))
                            {
                                if (userCount == 0)
                                {
                                    item["UserNameSignerOne"] = txtDisplayName.Text;
                                    item["PurposeOfSignatureSignerOne"] = ddlPurposeofSigning.SelectedItem.Text;
                                    item["DocumentStatusSignerOne"] = "This Document is " + status;
                                    item["DateSignedSignerOne"] = DateTime.Now.ToString();
                                    if (txtRejectedComments.Text != string.Empty)
                                    {
                                        item["RejectedComments"] = txtRejectedComments.Text;
                                        item["DocumentStatusSignerOne"] = "Document Rejected";
                                    }
                                }
                                else if (userCount == 1)
                                {
                                    item["UserNameSignerTwo"] = txtDisplayName.Text;
                                    item["PurposeOfSignatureSignerTwo"] = ddlPurposeofSigning.SelectedItem.Text;
                                    item["DocumentStatusSignerTwo"] = "This Document is " + status;
                                    item["DateSignedSignerTwo"] = DateTime.Now.ToString();
                                    if (txtRejectedComments.Text != string.Empty)
                                    {
                                        item["RejectedComments"] = txtRejectedComments.Text;
                                        item["DocumentStatusSignerTwo"] = "Document Rejected";
                                    }

                                }

                                spWeb.AllowUnsafeUpdates = true;
                                item.Update();
                                spWeb.AllowUnsafeUpdates = false;
                                updated = true;
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                lblMessage.Text = "Error : " + ex.Message;
            }
            return updated;
        }


        /// <summary>
        /// Method to update the document status
        /// </summary>
        /// <param name="status"></param>
        /// <returns>bool return true if updated</returns>
        protected bool UpdateEncryption()
        {
            bool updated = false;
            try
            {
                using (SPSite spSite = new SPSite(siteURL))
                {
                    using (SPWeb spWeb = spSite.OpenWeb())
                    {
                        SPQuery spQuery = new SPQuery();
                        string listQuery = string.Format("<Where><Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">{0}</Value></Eq></Where></Query>", documentID);
                        SPList spList = spWeb.Lists[listDocumentLibrary];
                        spQuery.Query = listQuery;
                        SPListItemCollection spListItems = spList.GetItems(spQuery);
                        foreach (SPListItem item in spListItems)
                        {
                            if (Convert.ToInt32(item["ID"]) == Convert.ToInt32(documentID))
                            {
                                if ((item["UserNameSignerOne"] != string.Empty) && (item["UserNameSignerTwo"] != string.Empty))
                                {
                                    item["EncryptedValue"] = EncryptStringValue(
                                                        item["UserNameSignerOne"].ToString().Trim() +
                                                        item["PurposeOfSignatureSignerOne"].ToString().Trim() + 
                                                        item["DocumentStatusSignerOne"].ToString().Trim() +
                                                        item["DateSignedSignerOne"].ToString().Trim() + 
                                                        item["UserNameSignerTwo"].ToString().Trim() +
                                                        item["PurposeOfSignatureSignerTwo"].ToString().Trim() + 
                                                        item["DocumentStatusSignerTwo"].ToString().Trim() +
                                                        item["DateSignedSignerTwo"]);
                                    item["DocumentValidity"] = "Valid";
                                }
                                spWeb.AllowUnsafeUpdates = true;
                                item.Update();
                                spWeb.AllowUnsafeUpdates = false;
                                updated = true;
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                lblMessage.Text = "Error : " + ex.Message;
            }
            return updated;
        }
        /// <summary>
        /// Method to approve the content type Approval Status
        /// </summary>
        protected void UpdateApprovalStatus()
        {
            try
            {
                using (SPSite spSite = new SPSite(siteURL))
                {
                    using (SPWeb spWeb = spSite.OpenWeb())
                    {
                        SPQuery spQuery = new SPQuery();
                        string listQuery = string.Format("<Query><Where><And><Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">{0}</Value></Eq><And><IsNotNull><FieldRef Name=\"UserNameSignerOne\" /></IsNotNull><IsNotNull><FieldRef Name=\"UserNameSignerTwo\" /></IsNotNull></And></And></Where></Query>", documentID);
                        SPList spList = spWeb.Lists[listDocumentLibrary];
                        spQuery.Query = listQuery;
                        SPListItemCollection spListItems = spList.GetItems(spQuery);
                        foreach (SPListItem item in spListItems)
                        {
                            if (Convert.ToInt32(item["ID"]) == Convert.ToInt32(documentID))
                            {
                                if (txtRejectedComments.Text != string.Empty)
                                {
                                    item["_ModerationStatus"] = (int)SPModerationStatusType.Denied;
                                }
                                else
                                {
                                    item["_ModerationStatus"] = (int)SPModerationStatusType.Approved;
                                }
                                spWeb.AllowUnsafeUpdates = true;
                                item.Update();
                                spWeb.AllowUnsafeUpdates = false;
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                lblMessage.Text = "Error: " + ex.Message;
            }

        }


        /// <summary>
        /// Method to encypt a string value
        /// </summary>
        /// <param name="sData"></param>
        /// <returns></returns>
        protected string EncryptStringValue(string sData)
        {
            try
            {
                byte[] encData_byte = new byte[sData.Length];
                encData_byte = System.Text.Encoding.UTF8.GetBytes(sData);
                string encodedData = Convert.ToBase64String(encData_byte);
                return encodedData;

            }
            catch (Exception ex)
            {
                throw new Exception("Error in base64Encode" + ex.Message);
            }
        }


        /// <summary>
        /// Method to add workflow history
        /// </summary>
        /// <param name="status"></param>
        /// <returns>bool return true if updated</returns>
        protected void CreateWorkflowHistory(bool docUpdated)
        {
            try
            {
                using (SPSite spSite = new SPSite(siteURL))
                {
                    using (SPWeb spWeb = spSite.OpenWeb())
                    {
                        spWeb.AllowUnsafeUpdates = true;
                        SPList spListAddWorkflow = spWeb.Lists[listWorkFlowHistory];
                        SPListItem newHistory = spListAddWorkflow.Items.Add();
                        newHistory["Title"] = dtDocDetails.Rows[0]["ID"].ToString() + " - " + DateTime.Now.ToString();
                        newHistory["FileName"] = dtDocDetails.Rows[0]["FileLeafRef"].ToString();
                        newHistory["DateOccurred"] = DateTime.Now.ToString();
                        if (docUpdated)
                        {
                            if (txtRejectedComments.Text != string.Empty)
                            {
                                newHistory["EventType"] = ConfigurationSettings.AppSettings["Rejected"];
                                newHistory["Description"] = "Document : " + txtDocumentName.Text + " rejected by : " + txtDisplayName.Text;
                            }
                            else
                            {
                                newHistory["EventType"] = ConfigurationSettings.AppSettings["Signed"];
                                newHistory["Description"] = "Document : " + txtDocumentName.Text + " signed by : " + txtDisplayName.Text;
                            }
                        }
                        else
                        {
                            newHistory["EventType"] = ConfigurationSettings.AppSettings["Error"]; 
                            newHistory["Description"] = "Document has not been signed: " + txtDocumentName.Text;
                        }
                        newHistory["UserID"] = txtLoginName.Text;
                        newHistory.Update();
                        spWeb.AllowUnsafeUpdates = false;
                    }
                }
            }
            catch (Exception ex)
            {
                lblMessage.Text = "Error: " + ex.Message;
            }
        }
    }
}
